package com.njworkorder.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.njworkorder.DTO.CorInspectionInfo;
import com.njworkorder.DTO.CorWithDictionaryAddDto;
import com.njworkorder.DTO.ConstructionOccupyingRoadAddDto;
import com.njworkorder.DTO.SelectDTO.SelectCORList;
import com.njworkorder.Entity.*;
import com.njworkorder.Mapper.CorWithAssignmentMapper;
import com.njworkorder.Mapper.CorWithDictionaryMapper;
import com.njworkorder.Service.ConstructionOccupyingRoadService;
import com.njworkorder.Utils.Result;
import com.njworkorder.Utils.ResultUtil;
import com.njworkorder.VO.CORDetailsVo;
import com.njworkorder.VO.CORListVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

@Tag(name = "施工占道", description = "施工占道相关接口")
@RestController
@RequestMapping("/constructionOccupyingRoad")
public class ConstructionOccupyingRoadController {

    private static final Logger log = LoggerFactory.getLogger(ConstructionOccupyingRoadController.class);
    private final ConstructionOccupyingRoadService constructionOccupyingRoadService;
    private final CorWithDictionaryMapper corWithDictionaryMapper;
    private final CorWithAssignmentMapper corWithAssignmentMapper;
    private final ExecutorService executorService;
    public ConstructionOccupyingRoadController(ConstructionOccupyingRoadService constructionOccupyingRoadService,
                                               CorWithDictionaryMapper corWithDictionaryMapper,
                                               CorWithAssignmentMapper corWithAssignmentMapper, ExecutorService executorService) {
        this.constructionOccupyingRoadService = constructionOccupyingRoadService;
        this.corWithDictionaryMapper = corWithDictionaryMapper;
        this.corWithAssignmentMapper = corWithAssignmentMapper;
        this.executorService = executorService;
    }

    @Transactional
    @Operation(summary = "新增施工占道信息")
    @PostMapping("/addInfo")
    public Result<String> addInfo(@RequestBody ConstructionOccupyingRoadAddDto occupyingRoadAddDto,
                                  @RequestHeader("Create-Ap-Id") String createApId){

        ConstructionOccupyingRoad COR = new ConstructionOccupyingRoad();
        BeanUtils.copyProperties(occupyingRoadAddDto,COR);
        String CORId = UUID.randomUUID().toString().replace("-","");
        COR.setId(CORId);
        COR.setAuditStatus(0);
        COR.setCreateApId(createApId);

        List<CorWithDictionaryAddDto> corWithDictionaryAddDtoList = occupyingRoadAddDto.getCorWithDictionaryInfo();
        List<CorWithDictionary> corWithDictionaryList = new ArrayList<>();
        CorWithDictionary corWithDictionary;
        for (CorWithDictionaryAddDto corWithDictionaryAddDto : corWithDictionaryAddDtoList) {
            corWithDictionary = new CorWithDictionary();
            BeanUtils.copyProperties(corWithDictionaryAddDto,corWithDictionary);
            corWithDictionary.setCorId(CORId);
            corWithDictionaryList.add(corWithDictionary);
        }
        corWithDictionaryMapper.insert(corWithDictionaryList);

        String[] assignmentIds = occupyingRoadAddDto.getAssignmentIds();
        if (assignmentIds != null && assignmentIds.length > 0){
            List<CorWithAssignment> corWithAssignmentList = new ArrayList<>();
            CorWithAssignment corWithAssignment;
            for (String assignmentId : assignmentIds) {
                corWithAssignment = new CorWithAssignment();
                corWithAssignment.setAssignmentId(assignmentId);
                corWithAssignment.setCorId(CORId);
                corWithAssignmentList.add(corWithAssignment);
            }
            corWithAssignmentMapper.insert(corWithAssignmentList);
        }

        boolean save = constructionOccupyingRoadService.save(COR);
        if (save){
            return ResultUtil.success("添加成功");
        }
        return ResultUtil.fail("添加失败");
    }

    @Transactional
    @Operation(summary = "根据id更新施工占道信息")
    @PostMapping("/updateById/{id}")
    public Result<String> updateById(@RequestBody ConstructionOccupyingRoadAddDto occupyingRoadAddDto,
                           @PathVariable("id") String id){

        ConstructionOccupyingRoad COR = new ConstructionOccupyingRoad();
        BeanUtils.copyProperties(occupyingRoadAddDto,COR);
        COR.setId(id);


        LambdaQueryWrapper<CorWithDictionary> wrapper = new LambdaQueryWrapper<CorWithDictionary>()
                .eq(CorWithDictionary::getCorId, id);
        corWithDictionaryMapper.delete(wrapper);

        LambdaQueryWrapper<CorWithAssignment> wrapper1 = new LambdaQueryWrapper<CorWithAssignment>()
                .eq(CorWithAssignment::getCorId, id);
        corWithAssignmentMapper.delete(wrapper1);


        List<CorWithDictionaryAddDto> corWithDictionaryAddDtoList = occupyingRoadAddDto.getCorWithDictionaryInfo();
        List<CorWithDictionary> corWithDictionaryList = new ArrayList<>();
        CorWithDictionary corWithDictionary;
        for (CorWithDictionaryAddDto corWithDictionaryAddDto : corWithDictionaryAddDtoList) {
            corWithDictionary = new CorWithDictionary();
            BeanUtils.copyProperties(corWithDictionaryAddDto,corWithDictionary);
            corWithDictionary.setCorId(id);
            corWithDictionaryList.add(corWithDictionary);
        }
        corWithDictionaryMapper.insert(corWithDictionaryList);

        String[] assignmentIds = occupyingRoadAddDto.getAssignmentIds();
        if (assignmentIds != null && assignmentIds.length > 0){
            List<CorWithAssignment> corWithAssignmentList = new ArrayList<>();
            CorWithAssignment corWithAssignment;
            for (String assignmentId : assignmentIds) {
                corWithAssignment = new CorWithAssignment();
                corWithAssignment.setAssignmentId(assignmentId);
                corWithAssignment.setCorId(id);
                corWithAssignmentList.add(corWithAssignment);
            }
            corWithAssignmentMapper.insert(corWithAssignmentList);
        }

        return constructionOccupyingRoadService.updateById(COR) ? ResultUtil.success("更新成功") : ResultUtil.success("更新失败");
    }

    @Operation(summary = "根据id删除施工占道信息")
    @GetMapping("/deleteById")
    public Result<String> deleteById(@RequestParam("id") String id){
        boolean removeById = constructionOccupyingRoadService.removeById(id);

        LambdaQueryWrapper<CorWithDictionary> queryWrapper = new LambdaQueryWrapper<CorWithDictionary>()
                .eq(CorWithDictionary::getCorId,id);
        corWithDictionaryMapper.delete(queryWrapper);


        if (removeById){
            return ResultUtil.success("删除成功");
        }
        return ResultUtil.fail("删除失败");
    }

    @Operation(summary = "根据id查询施工占道信息")
    @GetMapping("/getDetailsById")
    public Result<CORDetailsVo> getDetailsById(@RequestParam("id") String id){

        CORDetailsVo CORDetailsVo = new CORDetailsVo();
        ConstructionOccupyingRoad byId = constructionOccupyingRoadService.getById(id);
        BeanUtils.copyProperties(byId,CORDetailsVo);


        LambdaQueryWrapper<CorWithDictionary> queryWrapper = new LambdaQueryWrapper<CorWithDictionary>()
                .eq(CorWithDictionary::getCorId,id);
        List<CorWithDictionary> corWithDictionaries = corWithDictionaryMapper.selectList(queryWrapper);
        CORDetailsVo.setCorWithDictionaryInfo(corWithDictionaries);


        MPJLambdaWrapper<CorWithAssignment> wrapper = new MPJLambdaWrapper<CorWithAssignment>()
                .selectAll(CorWithAssignment.class)

                .selectAs(Assignment::getTaskOrderNumber,CorInspectionInfo::getTaskOrderNumber)
                .selectAs(InspectionRegistration::getStartPileNumUp, CorInspectionInfo::getStartPileNumUp)
                .selectAs(InspectionRegistration::getStartPileNumDown, CorInspectionInfo::getStartPileNumDown)
                .selectAs(InspectionRegistration::getEndPileNumUp, CorInspectionInfo::getEndPileNumUp)
                .selectAs(InspectionRegistration::getEndPileNumDown, CorInspectionInfo::getEndPileNumDown)
                .selectAs(DiseaseRegistration::getPosition, CorInspectionInfo::getPosition)
                .selectAs(DiseaseRegistration::getImagePath, CorInspectionInfo::getImagePath)

                .leftJoin(Assignment.class, Assignment::getId, CorWithAssignment::getAssignmentId)
                .leftJoin(InspectionRegistration.class, InspectionRegistration::getId, Assignment::getInspectionInfo)
                .leftJoin(DiseaseRegistration.class, DiseaseRegistration::getInspectionRegistrationId, InspectionRegistration::getId)

                .eq(CorWithAssignment::getCorId, id);

        List<CorInspectionInfo> corInspectionInfos = corWithAssignmentMapper.selectJoinList(CorInspectionInfo.class, wrapper);

        CORDetailsVo.setCorInspectionInfos(corInspectionInfos);
        return ResultUtil.success(CORDetailsVo);
    }


    @Parameter(name = "audit_status", description = "审核状态（0待审核、1审核通过、2驳回）")
    @Operation(summary = "审核")
    @GetMapping("/audit")
    public Result<String> audit(@RequestParam("id") String id,@RequestParam("status") String audit_status){

        LambdaUpdateWrapper<ConstructionOccupyingRoad> updateWrapper = new LambdaUpdateWrapper<ConstructionOccupyingRoad>()
                .eq(ConstructionOccupyingRoad::getId,id)
                .set(ConstructionOccupyingRoad::getAuditStatus,audit_status);

        boolean update = constructionOccupyingRoadService.update(updateWrapper);
        if (update){
            return ResultUtil.success("审核成功");
        }
        return ResultUtil.fail("审核失败");
    }

    @Operation(summary = "获取施工占道列表")
    @PostMapping("/getList")
    public Result<IPage<CORListVo>> getCORList(@RequestBody SelectCORList selectCORList){
        IPage<CORListVo> list = constructionOccupyingRoadService.getList(selectCORList);
        return ResultUtil.success(list);
    }


//    @Cacheable(key = "#id",value = "corCache",unless = "#result == null")
//    @GetMapping("/getData")
//    public ConstructionOccupyingRoad getData(String id) {
//
//
//        CompletableFuture<List<ConstructionOccupyingRoad>> a = CompletableFuture.supplyAsync(() ->{
//                    LambdaQueryWrapper<ConstructionOccupyingRoad> wre = new LambdaQueryWrapper<ConstructionOccupyingRoad>()
//                            .apply("1=1");
//
//                    return constructionOccupyingRoadService.list();
//                },executorService);
//
//
//        return constructionOccupyingRoadService.getById(id);
//    }

    @GetMapping("/getData")
    public List<ConstructionOccupyingRoad> getData(String id) throws RuntimeException{

        List<ConstructionOccupyingRoad> list = new ArrayList<>();


//        LambdaQueryWrapper<ConstructionOccupyingRoad> wrapper = new LambdaQueryWrapper<ConstructionOccupyingRoad>()
//                .eq(ConstructionOccupyingRoad::getId,id);
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        list.addAll( constructionOccupyingRoadService.list(wrapper));
//
//        LambdaQueryWrapper<ConstructionOccupyingRoad> wrapper1 = new LambdaQueryWrapper<ConstructionOccupyingRoad>()
//                .eq(ConstructionOccupyingRoad::getId,id);
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        list.addAll(constructionOccupyingRoadService.list(wrapper1));


        CompletableFuture<List<ConstructionOccupyingRoad>> a = CompletableFuture.supplyAsync(() ->{
            LambdaQueryWrapper<ConstructionOccupyingRoad> wre = new LambdaQueryWrapper<ConstructionOccupyingRoad>()
                    .eq(ConstructionOccupyingRoad::getId,id);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return constructionOccupyingRoadService.list(wre);
        },executorService);


        CompletableFuture<List<ConstructionOccupyingRoad>> b = CompletableFuture.supplyAsync(() ->{
            LambdaQueryWrapper<ConstructionOccupyingRoad> wre = new LambdaQueryWrapper<ConstructionOccupyingRoad>()
                    .eq(ConstructionOccupyingRoad::getId,id);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return constructionOccupyingRoadService.list(wre);
        },executorService);


        try {
            CompletableFuture.allOf(a,b).get();
            list.addAll(a.get());
            list.addAll(b.get());
        } catch (Exception e) {
            log.error("获取数据失败",e);
        }


        return list;
    }

}
